<template>
    <div ref="threeContainer" class="three-container"></div>
</template>

<script>
//导入three.js
import * as THREE from 'three';
//导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
//导入gui控制器
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';
//导入gltf模型
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
//导入hdr环境贴图
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
//解壓器
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
//導入tween
import { Tween } from 'three/examples/jsm/libs/tween.module.js';
export default {
    name: 'ThreeScene',
    mounted() {
        this.initThree();
    },
    methods: {
        initThree() {
            // 创建GLTF加载器对象
            const loader1 = new GLTFLoader();
            // loader1.load('gltf模型.gltf', function (gltf) {
            //     console.log('控制台查看加载gltf文件返回的对象结构', gltf);
            //     console.log('gltf对象场景属性', gltf.scene);
            //     // 返回的场景对象gltf.scene插入到threejs场景中
            //     scene.add(gltf.scene);
            // })
            //加載環境贴图
            // let rebeLoader = new RGBELoader();
            // rebeLoader.load('envmap.hdr', function (texture) {
            //     // 环境贴图添加到场景中
            //     scene.background = texture;
            // });
            //實例化DRACO加载器
            const dracoLoader = new DRACOLoader();
            dracoLoader.setDecoderPath('three/examples/js/libs/draco/');
            //实例化加载器gltf
            const loader = new GLTFLoader();
            //加载环境贴图
            let textureLoader = new THREE.TextureLoader();
            // 创建场景
            const scene = new THREE.Scene();
            // 设置背景颜色（天蓝色）
            scene.background = new THREE.Color(0x87CEEB);
            //设置raycaster
            const raycaster = new THREE.Raycaster();
            // 设置相机
            const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
            camera.position.set(5, 5, 5);
            camera.lookAt(0, 0, 0);

            // 创建渲染器
            const renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setSize(window.innerWidth, window.innerHeight);
            this.$refs.threeContainer.appendChild(renderer.domElement);

            // 创建魔方
            const cubeSize = 3;
            const cubeGroup = new THREE.Group();

            // 魔方六面颜色配置
            const colors = [
                new THREE.Color(0xff0000),  // 右面 - 红
                new THREE.Color(0x0000ff),  // 左面 - 蓝
                new THREE.Color(0x00ff00),  // 顶面 - 绿
                new THREE.Color(0xffa500),  // 底面 - 橙
                new THREE.Color(0xffffff),  // 前面 - 白    
                new THREE.Color(0xffff00)   // 后面 - 黄
            ];

            // 创建3x3x3魔方
            for (let x = 0; x < cubeSize; x++) {
                for (let y = 0; y < cubeSize; y++) {
                    for (let z = 0; z < cubeSize; z++) {
                        // 跳过中心不可见的立方体
                        if (x === 1 && y === 1 && z === 1) continue;

                        // 创建小立方体
                        const materials = colors.map(color =>
                            new THREE.MeshBasicMaterial({ color: color })
                        );

                        const cube = new THREE.Mesh(
                            new THREE.BoxGeometry(0.95, 0.95, 0.95),
                            materials
                        );

                        // 设置位置
                        cube.position.set(
                            x - 1,  // 将坐标居中
                            y - 1,
                            z - 1
                        );
                        //創建射綫
                        const raycaster = new THREE.Raycaster();
                        //創建鼠標向量
                        const mouse = new THREE.Vector2();
                        // 鼠标点击事件
                        window.addEventListener('click', event => {
                            // 计算鼠标点击位置
                            mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
                            mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

                            //根據攝像機和鼠標發出射線
                            raycaster.setFromCamera(mouse, camera);
                            // 計算射線交集
                            const intersects = raycaster.intersectObjects([cube]);
                            console.log(intersects);

                            if (intersects.length > 0) {
                                const intersectedObject = intersects[0].object;
                                if (intersectedObject.material && intersectedObject.material.color) {
                                    intersectedObject.material.color.set(0xff0000);
                                } else {
                                    console.log('The intersected object does not have a material or a color property.');
                                }
                            }
                        });
                        cubeGroup.add(cube);
                    }
                }
            }

            //創建一個球
            const ball = new THREE.Mesh(
                new THREE.SphereGeometry(0.5, 32, 32),
                new THREE.MeshBasicMaterial({ color: 0x00ff00 })
            )
            ball.position.x = -4
            scene.add(ball)

            const tween = new Tween.Tween(ball.position)
               .to({ x: 4 }, 2000)
               .start();

            scene.add(cubeGroup);

            // 轨道控制器配置
            const controls = new OrbitControls(camera, renderer.domElement);
            controls.enableDamping = true;
            controls.dampingFactor = 0.05;
            controls.rotateSpeed = 0.5;

            // 动画循环
            const animate = () => {
                requestAnimationFrame(animate);
                controls.update();

                // 整体缓慢旋转
                cubeGroup.rotation.x += 0.005;
                cubeGroup.rotation.y += 0.005;

                renderer.render(scene, camera);

                //更新tween
                Tween.update();
            };

            animate();

            // 窗口resize处理
            window.addEventListener('resize', () => {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize(window.innerWidth, window.innerHeight);
            });
        }
    }
}
</script>

<style scoped>
body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}

.three-container {
    width: 100%;
    height: 100%;
}
</style>